var eventObj = require("../event");
var fs = require("fs");
var _ = require("underscore");
var baseInfoUtil = require("../baseInfo");

function TramStatus(options){
	this.tramCode = options.tramCode || '1001';
	  //该车所有相关的运行计划信息
	this.runPlan = options.runPlan || null;
	  //时间游标
	this.passTimeBySec = options.initTimeBySec;
	this.serviceNum = options.serviceNum || null;
	this.startTerminusCode;
	this.endTerminusCode;
	this.code;             //车辆编号
	this.lineCode;             //线路号
	this.latitude;             //纬度
	this.longtitude;           //经度
	this.direct;		     //上下行
	this.fromTerminus;         //上一站站台
	this.toTerminus;           //下一站站台
	this.distance = 0;			 //距前方车站的距离
	this.mileage = 0;             //里程
	this.speedLimit;          //限速值
	this.speed = 0;               //速度
	this.soonerOrLater;       //早晚点信息
	this.arrivingTime;           //到站时间
	this.faultStatus;          //错误信息
	this.driverCode = 200;           //驾驶员编号
	this.isInline = true;     //是否在线
	this.isError = false;     //是否存在异常
	this.runPercent;          //已运行区间百分比
	this.lastDate;               //最近一次接收数据的时间
	this.Length ;         //电车长度
	this.end ;				 //是否停止服务
	this.tramIp;				 //车辆IP
	this.totalLength = options.totalLength||0;      //车辆总里程
	
	this.currentSegment;       //当前车头所在区段
	this.runDistance = 3;          //当前车头所在区段越过的距离
	this.status = "offline";
	//用于判断该车是添加车辆还是从起点出发车辆
	this.tramStyle = options.tramStyle||null;

	//停车所需相关参数
	this.stopArgs = {
							isStop : true,
							waitTime : 0							
					 };
    this.reentryArgs = {
                           //折返次数
							reentryTimes : 0,
							//折返标记
							reentryFlag : false,
							//标记折返segment游标
							reentryIndex : 0   
                     };					 

	this.packetNum = 0  //车辆发包序号
    this.centerReplyArgs = {
		//是否注册标志
		registerFlag      : 0,
		//运行计划回复标志
		runArgsReplyFlag  : 0,
		//存储运行参数信息包中的包序号
		savedPacketNum        : 0
	};
	
	//---------------------------- 用于判断车辆是否刚进入区段 或 离开区段的属性
	this.outSegmentCode;
	this.inSegmentCode;
	this.runExecutor = options.runExecutor||null;
	this.currentSegmentIndex = 0;
	//保存正线segment的数组
	this.segmentArr = [];
	//用来标记路由第一个segmentCode,主要是添加车辆功能使用
	this.startSegmentCode = options.startSegmentCode||null;
    //保存当前路由
	this.currentRoute = null;
}

module.exports = TramStatus;

TramStatus.prototype.init = function(){
	//在大循环中只运行一次,配置基本参数
	var $this = this;
	var firstTerminus = $this.runPlan.path.split("-")[0];
    var secondTerminus = $this.runPlan.path.split("-")[1];
    $this.speed = $this.runPlan.avgSpeed;
    $this.status = "offline";
    $this.mileage = 0;
    $this.inSegmentCode = null;
    $this.outSegmentCode = null;
    $this.lineCode = 3;
    if(parseInt(firstTerminus) > parseInt(secondTerminus)){
	  	$this.direct = 'up';
		$this.railDirectType = 'up';
		$this.currentSegmentIndex = 323
	  }else{
	  	$this.direct = 'down';
		$this.railDirectType = 'down';
		$this.currentSegmentIndex = 1;
	}
	//$this.currentRoute = $this.runExecutor.getCurrentRouteByDirect($this.direct);
	//$this.getSegmentsForRoute($this.currentRoute);
	$this.createSegmentArrData();

    $this.currentSegment = $this.getSegment($this.currentSegmentIndex);
    $this.currentSection = $this.getSection($this.currentSegmentIndex);
	if($this.tramStyle === "addTram"){
		$this.distance = 0;
	}else{
		$this.distance = $this.currentSection.Length;
	}
	$this.fromTerminus = $this.currentSection.fromTerminus;
	$this.toTerminus = $this.currentSection.toTerminus;
    $this.runDistance = $this.currentSegment.Length;
}

TramStatus.prototype.run = function(){
	   var $this = this;
	/*if($this.centerReplyArgs.registerFlag!=1){
       $this.sendRegisterEventInfo();
	}
	
	if($this.centerReplyArgs.registerFlag ===1 && $this.centerReplyArgs.runArgsReplyFlag != 1){
       $this.sendRunArgsEventInfo();
	}*/
	//if($this.centerReplyArgs.registerFlag ===1 && $this.centerReplyArgs.runArgsReplyFlag ===1){
		
        if($this.reentryArgs.reentryTimes <= ($this.runPlan.runTimes-1) ){
        	if ($this.passTimeBySec >= $this.runPlan.startTime) {
        		$this.online();
		        if(!$this.reentryArgs.reentryFlag){
		        	if ($this.stopArgs.isStop) {
						$this.waitForStart();
					}
					else {
						$this.move();
					}
		        }else{
		            $this.reentry();
		        }
		    }else{
		    	console.log('waiting for the tram to start');
		    }   
       }
       $this.passTimeBySec +=  $this.runExecutor.updateInterval;
			
	//}
	$this.listenRegisterReply();
	$this.listenScheduleInfo();
	$this.listenRunArgsEventInfo();
}

/*停站等待*/
TramStatus.prototype.waitForStart = function(){
	    var $this = this;
        $this.speed = 0;
	    //当车辆驶出第一个segment时
		if ( $this.stopArgs.waitTime >= $this.runPlan.avgStopTime) {
                $this.currentSegmentIndex++;
				var next = $this.getSegment($this.currentSegmentIndex);
			  //  var currentSection = $this.getSection($this.currentSegmentIndex);
			       $this.currentSection = $this.getSection($this.currentSegmentIndex);
		            $this.fromTerminus = $this.currentSection.fromTerminus;
			        $this.toTerminus = $this.currentSection.toTerminus;
		            $this.distance = $this.currentSection.Length;
				if (next != null ) {
					$this.inSegmentCode = next.code;
					$this.outSegmentCode = $this.currentSegment.code; 
					$this.runDistance = 0;
					$this.currentSegment = next;
				}
				else {
					$this.stopArgs.waitTime = 0;
					$this.stopArgs.isStop = true;
				}
			    $this.start();	
		}else{
			//console.log('stop in station-------------------');
			//车辆启动时停止动作，理论上是车辆驶过第一个segment所需要的事件
			$this.stopArgs.waitTime += $this.runExecutor.updateInterval;
			
		}
}

/*车辆移动*/
TramStatus.prototype.move = function(){
	//通过判断车辆
	    var $this = this;
	    $this.speed = $this.runPlan.avgSpeed;
		//var  next = $this.currentSegment.getNext($this.direct);
		var next = $this.getSegment($this.currentSegmentIndex + 1);
		//判断位移是否越过当前区段
		if(next){
			if (($this.runDistance + Math.round($this.runPlan.avgSpeed/3.6*$this.runExecutor.updateInterval)) <= $this.currentSegment.Length) {
				$this.runDistance += Math.round($this.runPlan.avgSpeed/3.6*$this.runExecutor.updateInterval);
				$this.mileage += Math.round($this.runPlan.avgSpeed/3.6*$this.runExecutor.updateInterval);
				$this.outSegmentCode = null;
				$this.inSegmentCode = null;
				$this.distance = $this.currentSection.Length - $this.mileage;
				//在正线运行时记录总里程数据
				$this.totalLength +=  Math.round($this.runPlan.avgSpeed/3.6*$this.runExecutor.updateInterval);
		    }else{
				//计算车辆越过当前区段进入下一区段
				$this.mileage += Math.round($this.runPlan.avgSpeed/3.6*$this.runExecutor.updateInterval);
                if($this.mileage >= $this.currentSection.Length){
                	//马上进入到停车状态,进入到下一区间模式
		            $this.stop();
					$this.speed = 0;
		            $this.runDistance = $this.currentSegment.Length;
		            $this.mileage = 0;
		        }else{
		        	//此处overDistance逻辑有问题 待验证
		        	var overDistance = ($this.runDistance + Math.round($this.runPlan.avgSpeed/3.6*$this.runExecutor.updateInterval)) - $this.currentSegment.Length;
					$this.outSegmentCode = $this.currentSegment.code;
					$this.inSegmentCode = next.code;
					$this.runDistance = overDistance;
					$this.currentSegment = next;
					$this.distance = $this.currentSection.Length - $this.mileage;
					$this.currentSegmentIndex ++;
		        }
				
		    }
		}else{
                if (($this.runDistance + Math.round($this.runPlan.avgSpeed/3.6*$this.runExecutor.updateInterval)) <= $this.currentSegment.Length) {
	                $this.runDistance += Math.round($this.runPlan.avgSpeed/3.6*$this.runExecutor.updateInterval);
					$this.mileage += Math.round($this.runPlan.avgSpeed/3.6*$this.runExecutor.updateInterval);
					$this.totalLength += Math.round($this.runPlan.avgSpeed/3.6*$this.runExecutor.updateInterval);
					$this.outSegmentCode = null;
					$this.inSegmentCode = null;
					$this.distance = $this.currentSection.Length - $this.mileage;
                }else{               	
                	$this.outSegmentCode = null;
					$this.inSegmentCode = null;
                	$this.serviceNum ++;
                	$this.stopArgs.waitTime = 0;
                	$this.currentRoute = $this.currentRoute.next;
                	//进行折返
                	$this.getSegmentsForRoute($this.currentRoute);
                	$this.currentSegmentIndex = 0;
                    //使大循环进入到折返逻辑函数中
	                $this.reentryArgs.reentryFlag = true;
	                $this.mileage = 0;
	                $this.runDistance = 0;
	                $this.totalLength = 0;
                }

		}
		
}
//折返函数
TramStatus.prototype.reentry = function(){
	var $this = this;
	$this.speed = $this.runPlan.avgSpeed;
	var currentSegmentCode = $this.segmentArr[$this.currentSegmentIndex].itemCode;
	var actualDirect = $this.segmentArr[$this.currentSegmentIndex].actualDirect;
	var sectionCode = $this.segmentArr[$this.currentSegmentIndex].sectionCode;
	$this.currentSection = baseInfoUtil.getSectionByCode(sectionCode);
	$this.currentSegment = $this.runExecutor.getSegmentStatusByCode(currentSegmentCode);
	//车辆方向与path中约定的方向一致
	$this.direct = actualDirect;
	$this.fromTerminus = $this.currentSection.fromTerminus;
	$this.toTerminus = $this.currentSection.toTerminus;

	if(($this.runDistance + Math.round($this.runPlan.avgSpeed/3.6*$this.runExecutor.updateInterval)) <= $this.currentSegment.Length){
		$this.inSegmentCode = $this.currentSegment.code;
		$this.runDistance += Math.round($this.runPlan.avgSpeed/3.6*$this.runExecutor.updateInterval);
		$this.mileage += Math.round($this.runPlan.avgSpeed/3.6*$this.runExecutor.updateInterval);
		$this.outSegmentCode = null;
		//$this.inSegmentCode = null;
		$this.distance = $this.currentSection.Length - $this.mileage;
	}else{
		//计算车辆越过当前区段进入下一区段
		//$this.mileage += Math.round(this.speed/3.6*$this.runExecutor.updateInterval);
		//如果还是在折返区段内
		if ($this.currentSegmentIndex < $this.segmentArr.length-1){
			$this.currentSegmentIndex++;
			$this.runDistance = 0;
			$this.outSegmentCode = $this.currentSegment.code;
			//此处inSegmentCode设置暂时如此
			$this.inSegmentCode = null;
			console.log($this.outSegmentCode+"------------+++++++");
			var nextDirect = $this.segmentArr[$this.currentSegmentIndex].actualDirect;
			if(actualDirect != nextDirect){
				$this.mileage = 0;
			}
			//进入到转折路径的最后一个区段
		}else{
			if(($this.runDistance + Math.round($this.runPlan.avgSpeed/3.6*$this.runExecutor.updateInterval)) <= $this.currentSegment.Length){
				$this.runDistance += Math.round($this.runPlan.avgSpeed/3.6*$this.runExecutor.updateInterval);
				$this.mileage += Math.round($this.runPlan.avgSpeed/3.6*$this.runExecutor.updateInterval);
				$this.outSegmentCode = null;
				$this.inSegmentCode = null;
				$this.distance = $this.currentSection.Length - $this.mileage;
			}else{
				//跳出折返逻辑,进入到正线逻辑
				// $this.distance = 0;
				$this.mileage = 0;
				$this.inSegmentCode = null;
				$this.outSegmentCode = $this.currentSegment.code;
				$this.reentryArgs.reentryFlag = false;
				$this.stopArgs.isStop = true;
				$this.currentSegmentIndex = 0;
				$this.currentRoute = $this.currentRoute.next;
				$this.getSegmentsForRoute($this.currentRoute);
				$this.currentSegment = $this.getSegment($this.currentSegmentIndex);
				$this.runDistance = $this.currentSegment.Length;
				$this.currentSection = baseInfoUtil.getSectionByCode($this.segmentArr[$this.currentSegmentIndex].sectionCode);
				$this.distance = $this.currentSection.Length;
				$this.fromTerminus = $this.currentSection.fromTerminus;
				$this.toTerminus = $this.currentSection.toTerminus;
				$this.direct = $this.currentRoute.direct;
			}
		}
	}

}

TramStatus.prototype.createSegmentArrData() = function(){
	var basicData = eval("(" + fs.readFileSync("./datas/segment.json", "utf-8")+ ")");
	console.log(basicData);
}

//发送车载状态包
TramStatus.prototype.sendStatusEventInfo = function(){
	var $this = this;
	var tempobj = {
	   "tramCode" : $this.tramCode,
       "currentSegment" : $this.currentSegment,
       "runDistance" : $this.runDistance,
       "direct" : $this.direct,
       "speed" : $this.speed,
       "lineCode" : $this.lineCode,
       "serviceNum" : $this.serviceNum,
       "distance": $this.distance,
      // "mileage" : $this.mileage,
       "totalLength" : $this.totalLength,
       "fromTerminus" : $this.fromTerminus,
       "toTerminus" : $this.toTerminus,
       "driverNum" : $this.driverCode,
       "packetNum" : $this.packetNum,
       "totalLength" : $this.totalLength,
       "isStop" : $this.stopArgs.isStop
	}
	$this.packetNum ++;
	console.log(tempobj);
	return tempobj;

}

TramStatus.prototype.stop = function(){
	    this.stopArgs.isStop = true;
		this.stopArgs.waitTime = 0;
}

TramStatus.prototype.start = function(){
	    this.stopArgs.isStop = false;
		this.stopArgs.waitTime = 0;
}

TramStatus.prototype.reset = function(){

}

TramStatus.prototype.online = function(){
	this.status = "online";
}

TramStatus.prototype.offline = function(){
	this.status = "offline";
}

TramStatus.prototype.isOnline = function(){
	return "online" === this.status;
}


//将正线所需的segments绑定到this对象
TramStatus.prototype.getSegmentsForRoute = function(currentRoute){
	var $this = this;
	if($this.segmentArr.length > 0){
		$this.segmentArr.splice(0,$this.segmentArr.length-1);
	}
	if ($this.startSegmentCode) {
		//首先需要在路径中找到该segment元素
		var item = null;
		_.forEach(currentRoute.routeItems,function(e){
			if (e.itemCode === $this.startSegmentCode) {
               item = e;
			};
		});
		var index = _.indexOf(currentRoute.routeItems,item);
		var restRouteItems = _.rest(currentRoute.routeItems,index);
		$this.segmentArr = _.filter(restRouteItems,function(e){
		  return e.type ==="segment"
	    })
	    //此处条件只进入一次
	    $this.startSegmentCode = null;
	}else{
		$this.segmentArr = _.filter(currentRoute.routeItems,function(e){
		  return e.type ==="segment"
	   })
	}
    		 
}
//根据游标获取当前segment
TramStatus.prototype.getSegment = function(index){
  var $this = this;	
  if (_.isNaN(index)||index >= $this.segmentArr.length||index < 0) {
     return null;
  };	
 // var segmentCode = $this.segmentArr[index].itemCode;
  var currentSegment = $this.segmentArr[index-1];
  return currentSegment; 

}
//根据当前游标获取当前section
TramStatus.prototype.getSection = function(index){
	var $this = this;
	if (_.isNaN(index)||index >= $this.segmentArr.length||index < 0) {
		return null;
	};
	var sectionCode = $this.segmentArr[index].sectionCode;
	var section = baseInfoUtil.getSectionByCode(sectionCode);
	return section;
}

